package org.zjt.akka;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.testkit.javadsl.TestKit;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
 * Description:  request 子、 response 父
 *
 * @author juntao.zhang
 * Date: 2018-06-26 下午10:10
 * @see akka.actor.AbstractActor#getSender  得到传递来的发送者
 */
@Slf4j
public class DeviceTest {

    @Slf4j
    public static class Device extends AbstractActor {


        final String groupId;

        final String deviceId;

        Optional<Double> lastTemperatureReading = Optional.empty();

        public Device(String groupId, String deviceId) {
            this.groupId = groupId;
            this.deviceId = deviceId;
        }

        /**
         * 创建actor Device
         * @param groupId
         * @param deviceId
         * @return
         */
        public static Props props(String groupId, String deviceId) {
            return Props.create(Device.class, groupId, deviceId);
        }


        @Override
        public void preStart() {
            log.info("Device actor {}-{} started", groupId, deviceId);
        }

        @Override
        public void postStop() {
            log.info("Device actor {}-{} stopped", groupId, deviceId);
        }

        @Override
        public Receive createReceive() {
            return receiveBuilder().match(ReadTemperature.class, r -> {

                log.info("-------回复父节点信息得到传递来的发送者 getSender()----------:{}",String.valueOf(getSender()));
                getSender().tell(new RespondTemperature(r.requestId + 1, lastTemperatureReading), getSelf());
            }).build();
        }

    }





    /**
     * 读取信息类
     */
    public static final class ReadTemperature {
        long requestId;

        public ReadTemperature(long requestId) {
            this.requestId = requestId;
        }
    }

    /**
     * 发送信息类
     */
    public static final class RespondTemperature {
        long requestId;
        Optional<Double> value;

        public RespondTemperature(long requestId, Optional<Double> value) {
            this.requestId = requestId;
            this.value = value;
        }
    }


    ActorSystem system ;

    @Before
    public void startup() {
        system = ActorSystem.create("testSystem");
    }



    @After
    public void shutdown() throws InterruptedException {
        TimeUnit.SECONDS.sleep(20);
        system.terminate();
    }


    @Test
    public void testReplyWithEmptyReadingIfNoTemperatureIsKnown() {
        TestKit probe = new TestKit(system);
        ActorRef deviceActor = system.actorOf(Device.props("group", "device"));

        log.info("-----------------:{}",String.valueOf(probe.getRef()));

        // 执行request 和 response 操作。
        deviceActor.tell(new ReadTemperature(42L), probe.getRef());

        // response
        RespondTemperature response = probe.expectMsgClass(RespondTemperature.class);
        assertEquals(42L, response.requestId);
        assertEquals(Optional.empty(), response.value);
    }

}
